package com.powernode.ssm.utils;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class IpUtils {

    /**
     * 获取客户端真实IP地址，支持IPv4/IPv6，过滤特殊IP如本地环回、unknown等
     *
     * @param request HttpServletRequest
     * @return 真实客户端IP地址，如果无法获取则返回 null 或默认值（比如 127.0.0.1）
     */
    public static String getClientIp(HttpServletRequest request) {
        if (request == null) {
            return null;
        }

        // 代理服务器可能设置的HTTP头，按优先级从前往后尝试获取IP
        String[] headersToCheck = {
                "X-Forwarded-For",
                "Proxy-Client-IP",
                "WL-Proxy-Client-IP",
                "HTTP_X_FORWARDED_FOR",
                "HTTP_X_FORWARDED",
                "HTTP_X_CLUSTER_CLIENT_IP",
                "HTTP_CLIENT_IP",
                "HTTP_FORWARDED_FOR",
                "HTTP_FORWARDED",
                "HTTP_VIA",
                "REMOTE_ADDR"
        };

        String ip = null;

        // 1. 尝试从 HTTP 头中获取 IP
        for (String header : headersToCheck) {
            ip = request.getHeader(header);
            if (isValidIp(ip)) {
                break;
            }
        }

        // 2. 如果 HTTP 头中没有有效IP，则使用 getRemoteAddr()
        if (!isValidIp(ip)) {
            ip = request.getRemoteAddr();
        }

        // 3. X-Forwarded-For 可能包含多个IP，如 "客户端IP, 代理1IP, 代理2IP"
        if (ip != null && ip.contains(",")) {
            // 取第一个非 unknown、非空、有效的IP
            List<String> ipList = Arrays.stream(ip.split(","))
                    .map(String::trim)
                    .filter(IpUtils::isValidIp)  // 只保留有效的IP
                    .collect(Collectors.toList());

            if (!ipList.isEmpty()) {
                ip = ipList.get(0); // 第一个有效IP认为是客户端真实IP
            } else {
                ip = null; // 所有IP都无效，则置空
            }
        }

        // 4. 如果最终IP仍然无效，返回 null 或者你可以指定一个默认值，比如 "127.0.0.1"
        return ip;
    }

    /**
     * 判断一个IP字符串是否是有效的IP地址（过滤掉 unknown、空、本地环回等）
     *
     * @param ip IP地址字符串
     * @return 是否是有效IP（非空、非unknown、非本地环回等）
     */
    public static boolean isValidIp(String ip) {
        if (ip == null || ip.trim().isEmpty() || "unknown".equalsIgnoreCase(ip.trim())) {
            return false;
        }

        String trimmedIp = ip.trim();

        // 过滤掉 IPv4 和 IPv6 的本地环回地址
        if ("127.0.0.1".equals(trimmedIp) || "0:0:0:0:0:0:0:1".equals(trimmedIp) || "::1".equalsIgnoreCase(trimmedIp)) {
            return false; // 可根据需求决定是否返回true，这里选择过滤掉本地环回
        }

        // 可选：过滤掉一些无意义的IP，如 0.0.0.0, ::
        if ("0.0.0.0".equals(trimmedIp) || "::".equals(trimmedIp)) {
            return false;
        }

        // 可根据需求，进一步用正则表达式验证是否是合法IPv4或IPv6地址
        // 这里简化处理，只要不是上述特殊值，就认为是有效IP（实际项目中可加强校验）

        return true;
    }
}
